﻿using UnityEngine;
using System.Collections.Generic;

public class CameraTool : MonoBehaviour
{
    static private CameraTool tool;
    static public CameraTool Instance
    {
        get
        {
            return tool;
        }
    }

    public Camera battleCamera;
    public Camera sceneCamera;
    public Transform mainPlayer;
    public Dictionary<GameObject, List<Material>> currentOcclusion = new Dictionary<GameObject, List<Material>>();
    //存放工会建筑物
    //List<GameObject> union = new List<GameObject>();

    void Awake()
    {
        tool = this;
        battleCamera.transform.parent.parent.GetComponent<Battle.View.BattleCamera>().Awake();
    }

    public void SwitchBattleCamera()
    {
        battleCamera.transform.parent.parent.gameObject.SetActive(true);
        sceneCamera.gameObject.SetActive(false);
        battleCamera.tag = "MainCamera";
        sceneCamera.tag = "Untagged";
    }
    public void SwitchSceneCamera()
    {
        battleCamera.transform.parent.parent.gameObject.SetActive(false);
        sceneCamera.gameObject.SetActive(true);
        battleCamera.tag = "Untagged";
        sceneCamera.tag = "MainCamera";
    }

    public void setSceneCameraFov(float fov)
    {
        sceneCamera.GetComponent<Camera>().fieldOfView = fov;
    }

    public float getSceneCameraFov()
    {
        return sceneCamera.GetComponent<Camera>().fieldOfView;
    }

    public void SetMainPlayer(Transform mainPlayer)
    {
        this.mainPlayer = mainPlayer;
    }



    public void Update()
    {
        if (sceneCamera.gameObject.activeSelf && sceneCamera.enabled && mainPlayer != null)
        {
            //if (union.Count > 0)
            //{
            //    for (int i = 0; i < union.Count; i++)
            //    {
            //        HideRender(union[i], true);
            //    }
            //    union.Clear();
            //}
            Vector3 direction = mainPlayer.position - sceneCamera.transform.position;
            Ray ray = new Ray(sceneCamera.transform.position - direction, direction * 2);
#if UNITY_EDITOR
            Debug.DrawRay(sceneCamera.transform.position - direction, direction * 2, Color.yellow);
#endif
            var hits = Physics.RaycastAll(ray, direction.magnitude * 2, 1 << LayerName.Occlusion);
            if (hits == null || hits.Length == 0)
            {
                RevertAll();
                return;
            }
            
            Dictionary<GameObject, List<Material>> tmp = new Dictionary<GameObject, List<Material>>();
            for (int i = 0; i < hits.Length; ++i)
            {
                GameObject gobj = hits[i].transform.gameObject;
                if (currentOcclusion.ContainsKey(gobj))
                {
                    tmp[gobj] = currentOcclusion[gobj];
                    currentOcclusion.Remove(gobj);
                }
                else
                {
                    tmp[gobj] = SetTransRender(gobj);
                    //HideRender(gobj, false);
                    //union.Add(gobj);
                }
            }
            foreach (var kvp in currentOcclusion)
            {
                ResetRender(kvp.Key);
            }
            currentOcclusion = tmp;
        }
        else
        {
            RevertAll();
        }
    }

    private void ResetRender(GameObject obj)
    {
        if (obj != null)
        {
            //var ms = obj.GetComponent<Renderer>().materials;
            obj.GetComponent<Renderer>().materials = currentOcclusion[obj].ToArray();
        }
    }

    private void RevertAll()
    {
        if (currentOcclusion.Count > 0)
        {
            foreach (var kvp in currentOcclusion)
            {
                ResetRender(kvp.Key);
            }
            currentOcclusion.Clear();
        }
    }

    private List<Material> SetTransRender(GameObject obj)
    {
        Renderer rend = obj.GetComponent<Renderer>();
        if (rend == null)
        {
            Debug.LogError("Occlusion error " + obj.name);
            return null;
        }
        else
        {
            List<Material> material = new List<Material>();
            var mt = rend.materials;
            for (int i = 0; i < mt.Length; ++i)
            {
                Material m = Instantiate(mt[i]);
                material.Add(m);
                mt[i].shader = Shader.Find("Legacy Shaders/Transparent/Diffuse");
                //if (!obj.name.StartsWith("guild_obj_302"))
                mt[i].color = new Color(1, 1, 1, 0.3f);
            }
            return material;
        }
    }

    private void HideRender(GameObject obj,bool isHide)
    {
        if (obj.name.StartsWith("guild_obj_302"))
        {
            obj.GetComponent<MeshRenderer>().enabled = isHide;
            /*var colliders = obj.GetComponents<MeshCollider>();
            if(colliders!=null)
            {
                foreach(var collider in colliders)
                {
                    collider.enabled = isHide;
                }
            }
            */
        }
    }

    public void ResetSceneBloomEffect()
    {
        var activeCamera = !sceneCamera.gameObject.activeSelf ? battleCamera : sceneCamera;
        var activeScript = activeCamera.GetComponent<UnityStandardAssets.ImageEffects.BloomOptimized>();
        if (activeScript != null)
        {
            string str = "/" + UnityEngine.SceneManagement.SceneManager.GetActiveScene().name + @"/effect";
            var obj = GameObject.Find(str);
            if (obj != null)
            {
                var effectParam = obj.GetComponent<UnityStandardAssets.ImageEffects.BloomOptimized>();
                if(effectParam !=null)
                {
                    activeScript.blurIterations = effectParam.blurIterations;
                    activeScript.blurSize = effectParam.blurSize;
                    activeScript.blurType = effectParam.blurType;
                    activeScript.intensity = effectParam.intensity;
                    activeScript.threshold = effectParam.threshold;
                }
            }
        }
    }

}
